home *** CD-ROM | disk | FTP | other *** search
/ Internet Info 1994 March / Internet Info CD-ROM (Walnut Creek) (March 1994).iso / networking / cisco / tacacsd.shar / xtacacsd / syslog.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-08-07  |  5.1 KB  |  212 lines

  1. /*
  2.  * Copyright (c) 1983, 1988 Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms are permitted provided
  6.  * that: (1) source distributions retain this entire copyright notice and
  7.  * comment, and (2) distributions including binaries display the following
  8.  * acknowledgement:  ``This product includes software developed by the
  9.  * University of California, Berkeley and its contributors'' in the
  10.  * documentation or other materials provided with the distribution and in
  11.  * all advertising materials mentioning features or use of this software.
  12.  * Neither the name of the University nor the names of its contributors may
  13.  * be used to endorse or promote products derived from this software without
  14.  * specific prior written permission.
  15.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  16.  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  17.  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  18.  */
  19.  
  20. #if defined(LIBC_SCCS) && !defined(lint)
  21. static char sccsid[] = "@(#)syslog.c    5.28 (Berkeley) 6/27/90";
  22. #endif /* LIBC_SCCS and not lint */
  23.  
  24. /*
  25.  * SYSLOG -- print message on log file
  26.  *
  27.  * This routine looks a lot like printf, except that it outputs to the
  28.  * log file instead of the standard output.  Also:
  29.  *    adds a timestamp,
  30.  *    prints the module name in front of the message,
  31.  *    has some other formatting types (or will sometime),
  32.  *    adds a newline on the end of the message.
  33.  *
  34.  * The output of this routine is intended to be read by syslogd(8).
  35.  *
  36.  * Author: Eric Allman
  37.  * Modified to use UNIX domain IPC by Ralph Campbell
  38.  */
  39.  
  40. #include <sys/types.h>
  41. #include <sys/socket.h>
  42. #include <sys/file.h>
  43. #include <sys/signal.h>
  44. #include <sys/syslog.h>
  45. #include <sys/uio.h>
  46. #include <sys/wait.h>
  47. #include <netdb.h>
  48. #include <string.h>
  49. #include <varargs.h>
  50. #include <paths.h>
  51. #include <stdio.h>
  52.  
  53. #define    _PATH_LOGNAME    "/dev/log"
  54.  
  55. static int    LogFile = -1;        /* fd for log */
  56. static int    connected;        /* have done connect */
  57. static int    LogStat = 0;        /* status bits, set by openlog() */
  58. static char    *LogTag = "syslog";    /* string to tag the entry with */
  59. static int    LogFacility = LOG_USER;    /* default facility code */
  60.  
  61. syslog(pri, fmt, args)
  62.     int pri, args;
  63.     char *fmt;
  64. {
  65.     vsyslog(pri, fmt, &args);
  66. }
  67.  
  68. vsyslog(pri, fmt, ap)
  69.     int pri;
  70.     register char *fmt;
  71.     va_list ap;
  72. {
  73.     extern int errno;
  74.     register int cnt;
  75.     register char *p;
  76.     time_t now, time();
  77.     int fd, saved_errno;
  78.     char tbuf[2048], fmt_cpy[1024], *stdp, *ctime();
  79.  
  80.     saved_errno = errno;
  81.  
  82.     /* see if we should just throw out this message */
  83.     if (!LOG_MASK(LOG_PRI(pri)) || (pri &~ (LOG_PRIMASK|LOG_FACMASK)))
  84.         return;
  85.     if (LogFile < 0 || !connected)
  86.         openlog(LogTag, LogStat | LOG_NDELAY, 0);
  87.  
  88.     /* set default facility if none specified */
  89.     if ((pri & LOG_FACMASK) == 0)
  90.         pri |= LogFacility;
  91.  
  92.     /* build the message */
  93.     (void)time(&now);
  94.     (void)sprintf(tbuf, "<%d>%.15s ", pri, ctime(&now) + 4);
  95.     for (p = tbuf; *p; ++p);
  96.     if (LogStat & LOG_PERROR)
  97.         stdp = p;
  98.     if (LogTag) {
  99.         (void)strcpy(p, LogTag);
  100.         for (; *p; ++p);
  101.     }
  102.     if (LogStat & LOG_PID) {
  103.         (void)sprintf(p, "[%d]", getpid());
  104.         for (; *p; ++p);
  105.     }
  106.     if (LogTag) {
  107.         *p++ = ':';
  108.         *p++ = ' ';
  109.     }
  110.  
  111.     /* substitute error message for %m */
  112.     {
  113.         register char ch, *t1, *t2;
  114.         char *strerror();
  115.  
  116.         for (t1 = fmt_cpy; ch = *fmt; ++fmt)
  117.             if (ch == '%' && fmt[1] == 'm') {
  118.                 ++fmt;
  119.                 for (t2 = strerror(saved_errno);
  120.                     *t1 = *t2++; ++t1);
  121.             }
  122.             else
  123.                 *t1++ = ch;
  124.         *t1 = '\0';
  125.     }
  126.  
  127.     (void)vsprintf(p, fmt_cpy, ap);
  128.  
  129.     cnt = strlen(tbuf);
  130.  
  131.     /* output to stderr if requested */
  132.     if (LogStat & LOG_PERROR) {
  133.         struct iovec iov[2];
  134.         register struct iovec *v = iov;
  135.  
  136.         v->iov_base = stdp;
  137.         v->iov_len = cnt - (stdp - tbuf);
  138.         ++v;
  139.         v->iov_base = "\n";
  140.         v->iov_len = 1;
  141.         (void)writev(2, iov, 2);
  142.     }
  143.  
  144.     /* output the message to the local logger */
  145.     if (send(LogFile, tbuf, cnt, 0) >= 0 || !(LogStat&LOG_CONS))
  146.         return;
  147.  
  148.     /*
  149.      * output the message to the console; don't worry about
  150.      * blocking, if console blocks everything will.
  151.      */
  152.     if ((fd = open(_PATH_CONSOLE, O_WRONLY, 0)) < 0)
  153.         return;
  154.     (void)strcat(tbuf, "\r\n");
  155.     cnt += 2;
  156.     p = index(tbuf, '>') + 1;
  157.     (void)write(fd, p, cnt - (p - tbuf));
  158.     (void)close(fd);
  159. }
  160.  
  161. static struct sockaddr SyslogAddr;    /* AF_UNIX address of local logger */
  162. /*
  163.  * OPENLOG -- open system log
  164.  */
  165. openlog(ident, logstat, logfac)
  166.     char *ident;
  167.     int logstat, logfac;
  168. {
  169.     if (ident != NULL)
  170.         LogTag = ident;
  171.     LogStat = logstat;
  172.     if (logfac != 0 && (logfac &~ LOG_FACMASK) == 0)
  173.         LogFacility = logfac;
  174.     if (LogFile == -1) {
  175.         SyslogAddr.sa_family = AF_UNIX;
  176.         strncpy(SyslogAddr.sa_data, _PATH_LOGNAME,
  177.             sizeof(SyslogAddr.sa_data));
  178.         if (LogStat & LOG_NDELAY) {
  179.             LogFile = socket(AF_UNIX, SOCK_DGRAM, 0);
  180.             fcntl(LogFile, F_SETFD, 1);
  181.         }
  182.     }
  183.     if (LogFile != -1 && !connected &&
  184.         connect(LogFile, &SyslogAddr, sizeof(SyslogAddr)) != -1)
  185.         connected = 1;
  186. }
  187.  
  188. /*
  189.  * CLOSELOG -- close the system log
  190.  */
  191. closelog()
  192. {
  193.     (void) close(LogFile);
  194.     LogFile = -1;
  195.     connected = 0;
  196. }
  197.  
  198. static int    LogMask = 0xff;        /* mask of priorities to be logged */
  199. /*
  200.  * SETLOGMASK -- set the log mask level
  201.  */
  202. setlogmask(pmask)
  203.     int pmask;
  204. {
  205.     int omask;
  206.  
  207.     omask = LogMask;
  208.     if (pmask != 0)
  209.         LogMask = pmask;
  210.     return (omask);
  211. }
  212.